package com.sykj.seaflow.warm.module.instance.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.sykj.seaflow.common.base.exception.CommonException;
import com.sykj.seaflow.common.base.util.LoginHelper;
import com.sykj.seaflow.sys.remote.api.SysUserApi;
import com.sykj.seaflow.sys.remote.bean.SysUserBean;
import com.sykj.seaflow.warm.module.design.entity.SeaFlowDesign;
import com.sykj.seaflow.warm.module.design.service.SeaFlowDesignService;
import com.sykj.seaflow.warm.module.instance.entity.SeaFlowUser;
import com.sykj.seaflow.warm.module.instance.mapper.SeaFlowInstanceMapper;
import com.sykj.seaflow.warm.module.instance.params.FlowInstanceStartParam;
import com.sykj.seaflow.warm.module.instance.service.FlowInstanceService;
import org.dromara.warm.flow.core.dto.FlowParams;
import org.dromara.warm.flow.core.entity.Definition;
import org.dromara.warm.flow.core.entity.Instance;
import org.dromara.warm.flow.core.enums.SkipType;
import org.dromara.warm.flow.core.service.DefService;
import org.dromara.warm.flow.core.service.InsService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@AllArgsConstructor
@Service
public class FlowInstanceServiceImpl implements FlowInstanceService {
    private final InsService  insService;
    private final DefService defService;
    private final SeaFlowDesignService designService;
    private final SysUserApi sysUserApi;
    private final SeaFlowInstanceMapper instanceMapper;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void start(FlowInstanceStartParam flowInstanceStartParam) {

        SeaFlowDesign seaflowDesign = designService.getOne(Wrappers.<SeaFlowDesign>lambdaQuery().eq(SeaFlowDesign::getDefId, flowInstanceStartParam.getDefId()));
        if(seaflowDesign == null){
            throw  new CommonException("当前流程非最新使用版本，请刷新页面后重新尝试");
        }
        if(ObjectUtil.notEqual(seaflowDesign.getStatus(),"1")){
            throw  new CommonException("当前流程已停用");
        }
        Definition definition = defService.getById(flowInstanceStartParam.getDefId());

        String userId = LoginHelper.getUserIdAsString();
        Map<String, Object> variable = BeanUtil.beanToMap(flowInstanceStartParam);
        FlowParams flowParams = FlowParams.build().flowCode(definition.getFlowCode()).handler(userId).
                permissionFlag(Arrays.asList(userId)).variable(variable).ext(JSONUtil.toJsonStr(flowInstanceStartParam.getUserPosition())).skipType(SkipType.PASS.getKey());
        // 业务id 为什么不能为空？
        Instance instance = insService.start("1", flowParams);
        insService.skipByInsId(instance.getId(), flowParams);
    }

    @Override
    public List<SeaFlowUser> approveList(List<Long> instanceIds) {
        // 流程实例的 待办人
        QueryWrapper<Object> query = Wrappers.query();
        query.in("inst.id", instanceIds);
        query.eq("fuser.del_flag", "0");
        List<SeaFlowUser> seaflowUsers = instanceMapper.approveList(query);
        if(ObjectUtil.isNotEmpty(seaflowUsers)){
            List<Long> userIds = seaflowUsers.stream().map(SeaFlowUser::getId).distinct().collect(Collectors.toList());// .toList();
            List<SysUserBean> users = sysUserApi.getUsers(userIds);
            for (SeaFlowUser seaflowUser : seaflowUsers) {
                users.stream().filter(user -> user.getId().equals(seaflowUser.getId())).findFirst().ifPresent(
                        user -> seaflowUser.setName(user.getNick()));
            }
        }
        return seaflowUsers;
    }
}
